﻿///////////////////////////////////////////////////////////////
// Обработки событий

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	РежимУдаления = "Полный";
	Элементы.КомандаДалее.Видимость = Ложь;
КонецПроцедуры

&НаКлиенте
Процедура РежимУдаленияПриИзменении(Элемент)
	Если РежимУдаления = "Полный" Тогда
		Элементы.КомандаДалее.Видимость   = Ложь;
		Элементы.КомандаУдалить.Видимость = Истина;
		Элементы.КомандаУдалить.КнопкаПоУмолчанию = Истина;
	ИначеЕсли РежимУдаления = "Выборочный" Тогда
		Элементы.КомандаДалее.Видимость = Истина;
		Элементы.КомандаУдалить.Видимость = Ложь;
		Элементы.КомандаДалее.КнопкаПоУмолчанию = Истина;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПометкаПриИзменении(Элемент)
	ТекущиеДанные = Элементы.СписокПомеченныхНаУдаление.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	УстановитьПометкуВСписке(ТекущиеДанные, ТекущиеДанные.Пометка, Истина);
КонецПроцедуры

&НаКлиенте
Процедура КомандаСписокПомеченныхУстановитьВсе()
	ЭлементыСписка = СписокПомеченныхНаУдаление.ПолучитьЭлементы();
	Для каждого Элемент Из ЭлементыСписка Цикл
		УстановитьПометкуВСписке(Элемент, Истина, Истина);
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура КомандаСписокПомеченныхСнятьВсе()
	ЭлементыСписка = СписокПомеченныхНаУдаление.ПолучитьЭлементы();
	Для каждого Элемент Из ЭлементыСписка Цикл
		УстановитьПометкуВСписке(Элемент, Ложь, Истина);
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ДеревоНеудаленныхОбъектовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	ТекущиеДанные = Элементы.ДеревоНеудаленныхОбъектов.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Если ТекущиеДанные.ПолучитьЭлементы().Количество() = 0 Тогда
		// это строка отображает объект, из-за которого не удалось удалить помеченный и выбранный
		СтандартнаяОбработка = Ложь;
		ПоказатьЗначение( ,ТекущиеДанные.Значение);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СписокПомеченныхНаУдалениеВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	// Вставить содержимое обработчика.
	ТекущиеДанные = Элементы.СписокПомеченныхНаУдаление.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Если ТекущиеДанные.ПолучитьЭлементы().Количество() = 0 Тогда
		// это строка отображает помеченный на удаление объект
		СтандартнаяОбработка = Ложь;
		ПоказатьЗначение( ,ТекущиеДанные.Значение);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьДалее()
	ТекущаяСтраница = Элементы.СтраницыФормы.ТекущаяСтраница;
	Если ТекущаяСтраница = Элементы.ВыборРежимаУдаления Тогда
		Состояние(НСтр("ru ='Выполняется поиск помеченных на удаление объектов'", "ru"));
		ЗаполнениеДереваПомеченныхНаУдаление();
		Элементы.КомандаДалее.Видимость           = Ложь;
		Элементы.КомандаУдалить.Видимость         = Истина;
		Элементы.КомандаУдалить.КнопкаПоУмолчанию = Истина;
		Элементы.СтраницыФормы.ТекущаяСтраница = Элементы.ПомеченныеНаУдаление;
	ИначеЕсли ТекущаяСтраница = Элементы.РезультатыУдаления Тогда
		Элементы.КомандаДалее.Видимость    = Ложь;
		Элементы.КомандаУдалить.Видимость  = Ложь;
		Элементы.Закрыть.КнопкаПоУмолчанию = Истина;
		Элементы.СтраницыФормы.ТекущаяСтраница = Элементы.ПричиныНеудаления;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьУдаление()
	Если РежимУдаления = "Полный" Тогда
		Состояние(НСтр("ru ='Выполняется поиск и удаление помеченных объектов'", "ru"));
	Иначе
		Состояние(НСтр("ru ='Выполняется удаление выбранных объектов'", "ru"));
	КонецЕсли;
	
	УдалениеВыбранныхНаСервере();
КонецПроцедуры

/////////////////////////////////////////////////////////////////////////
// Вспомогательные процедуры

&НаСервере
Функция НайтиИлиДобавитьВетвьДерева(СтрокиДерева, Значение, Представление, Пометка)
	// Попытка найти существующую ветвь в СтрокиДерева без вложенных
	Ветвь = СтрокиДерева.Найти(Значение, "Значение", Ложь);
	Если Ветвь = Неопределено Тогда
		// Такой ветки нет, создадим новую
		Ветвь = СтрокиДерева.Добавить();
		Ветвь.Значение      = Значение;
		Ветвь.Представление = Представление;
		Ветвь.Пометка       = Пометка;
	КонецЕсли;

	Возврат Ветвь;
КонецФункции

&НаСервере
Функция НайтиИлиДобавитьВетвьДереваСКартинкой(СтрокиДерева, Значение, Представление, НомерКартинки)
	// Попытка найти существующую ветвь в СтрокиДерева без вложенных
	Ветвь = СтрокиДерева.Найти(Значение, "Значение", Ложь);
	Если Ветвь = Неопределено Тогда
		// Такой ветки нет, создадим новую
		Ветвь = СтрокиДерева.Добавить();
		Ветвь.Значение      = Значение;
		Ветвь.Представление = Представление;
		Ветвь.НомерКартинки = НомерКартинки;
	КонецЕсли;

	Возврат Ветвь;
КонецФункции

&НаСервере
Процедура ЗаполнениеДереваПомеченныхНаУдаление()
	// Заполнение дерева помеченных на удаление
	ДеревоПомеченных = РеквизитФормыВЗначение("СписокПомеченныхНаУдаление");
	// обработка помеченных
	МассивПомеченных = НайтиПомеченныеНаУдаление();
	Для каждого МассивПомеченныхЭлемент Из МассивПомеченных Цикл
		ОбъектМетаданныхЗначение = МассивПомеченныхЭлемент.Метаданные().ПолноеИмя();
		ОбъектМетаданныхПредставление = МассивПомеченныхЭлемент.Метаданные().Представление();
		СтрокаОбъектаМетаданных = НайтиИлиДобавитьВетвьДерева(ДеревоПомеченных.Строки, ОбъектМетаданныхЗначение, ОбъектМетаданныхПредставление, Истина);
		НайтиИлиДобавитьВетвьДерева(СтрокаОбъектаМетаданных.Строки, МассивПомеченныхЭлемент, Строка(МассивПомеченныхЭлемент) + " - " + ОбъектМетаданныхПредставление, Истина);
	КонецЦикла;
	ДеревоПомеченных.Строки.Сортировать("Значение", Истина);
	Для каждого СтрокаОбъектаМетаданных Из ДеревоПомеченных.Строки Цикл
		// создать представление для строк, отображающих ветвь объекта метаданных
		СтрокаОбъектаМетаданных.Представление = СтрокаОбъектаМетаданных.Представление + " (" + СтрокаОбъектаМетаданных.Строки.Количество() + ")";
	КонецЦикла;
	
	ЗначениеВРеквизитФормы(ДеревоПомеченных, "СписокПомеченныхНаУдаление");
КонецПроцедуры

&НаСервере
Процедура УдалениеВыбранныхНаСервере()
	Удаляемые = Новый Массив;
	Если РежимУдаления = "Полный" Тогда
		// При полном удалении получаем весь список помеченных на удаление
		Удаляемые = НайтиПомеченныеНаУдаление();
	Иначе
		// Заполняем массив ссылками на выбранные элементы, помеченные на удаление
		КоллекцияСтрокМетаданных = СписокПомеченныхНаУдаление.ПолучитьЭлементы();
		Для каждого СтрокаОбъектаМетаданных Из КоллекцияСтрокМетаданных Цикл
			КоллекцияСтрокСсылок = СтрокаОбъектаМетаданных.ПолучитьЭлементы();
			Для каждого СтрокаСсылки Из КоллекцияСтрокСсылок Цикл
				Если СтрокаСсылки.Пометка Тогда
					Удаляемые.Добавить(СтрокаСсылки.Значение);
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
	КонецЕсли;
	
	ИсходнаяСтраница = Элементы.СтраницыФормы.ТекущаяСтраница;
	Элементы.СтраницыФормы.ТекущаяСтраница = Элементы.РезультатыУдаления;
	
	// Выполняем удаление
	Найденные = Новый ТаблицаЗначений;
	Попытка
		МонопольныйДоступ = МонопольныйРежим();
		Если НЕ МонопольныйДоступ Тогда 
			УстановитьМонопольныйРежим(Истина);
		КонецЕсли;
		УдалитьОбъекты(Удаляемые, Истина, Найденные);
		Если НЕ МонопольныйДоступ Тогда 
			УстановитьМонопольныйРежим(Ложь);
		КонецЕсли;
	Исключение
		Элементы.СтраницыФормы.ТекущаяСтраница = ИсходнаяСтраница;
		ВызватьИсключение;
	КонецПопытки;
	
	// Создадим таблицу неудаленных объектов
	ДеревоНеудаленныхОбъектов.ПолучитьЭлементы().Очистить();
	Дерево = РеквизитФормыВЗначение("ДеревоНеудаленныхОбъектов");
	Для каждого Найденный Из Найденные Цикл
		Неудаленный = Найденный[0];
		Ссылающийся = Найденный[1];
		ОбъектМетаданныхСсылающегося = Найденный[2].Представление();
		ОбъектМетаданныхНеудаленногоЗначение = Неудаленный.Метаданные().ПолноеИмя();
		ОбъектМетаданныхНеудаленногоПредставление = Неудаленный.Метаданные().Представление();
		//ветвь метаданного
		СтрокаОбъектаМетаданных = НайтиИлиДобавитьВетвьДереваСКартинкой(Дерево.Строки, ОбъектМетаданныхНеудаленногоЗначение, ОбъектМетаданныхНеудаленногоПредставление, 0);
		//ветвь не удаленного объекта
		СтрокаСсылкиНаНеудаленныйОбъектБД = НайтиИлиДобавитьВетвьДереваСКартинкой(СтрокаОбъектаМетаданных.Строки, Неудаленный, Строка(Неудаленный), 2);
		//ветвь ссылки на не удаленный объект
		НайтиИлиДобавитьВетвьДереваСКартинкой(СтрокаСсылкиНаНеудаленныйОбъектБД.Строки, Ссылающийся, Строка(Ссылающийся) + " - " + ОбъектМетаданныхСсылающегося, 1);
	КонецЦикла;
	Дерево.Строки.Сортировать("Значение", Истина);
	ЗначениеВРеквизитФормы(Дерево, "ДеревоНеудаленныхОбъектов");
	
	// Проверяем завершенность операции удаления
	// Посчитаем количество неудаленных, для этого подситаем в дереве ветви
	// второго уровны, где они и присутствуют
	НеудаленныхОбъектов = 0;
	Для каждого СтрокаОбъектаМетаданных Из Дерево.Строки Цикл
		НеудаленныхОбъектов = НеудаленныхОбъектов + СтрокаОбъектаМетаданных.Строки.Количество();
	КонецЦикла;
	
	УдаленныхОбъектов   = Удаляемые.Количество() - НеудаленныхОбъектов;
	
	СтрокаРезультатов = Строка(УдаленныхОбъектов) 
		+ НСтр("ru =' объектов удалено!'", "ru");
	Если НеудаленныхОбъектов > 0 Тогда
		СтрокаРезультатов = СтрокаРезультатов + Символы.ПС + Символы.ПС;
		СтрокаРезультатов = СтрокаРезультатов 
			+ НеудаленныхОбъектов 
			+ НСтр("ru =' объектов удалить невозможно - в информационной базе'", "ru") 
			+ Символы.ПС;
		СтрокаРезультатов = СтрокаРезультатов 
			+ НСтр("ru ='на них ссылаются другие объекты.'", "ru");
	КонецЕсли;
	
	Если ДеревоНеудаленныхОбъектов.ПолучитьЭлементы().Количество() = 0 Тогда
		// если удалилось все, на этом завершаем, даем посмотреть на результат и оставляем разрешенным только Закрыть
		Элементы.КомандаДалее.Видимость         = Ложь;
		Элементы.КомандаУдалить.Видимость       = Ложь;
		Элементы.Закрыть.КнопкаПоУмолчанию	    = Истина;
	Иначе
		// имеются неудаленные, разрешим переход на страницу причин неудаления
		Элементы.КомандаДалее.Видимость         = Истина;
		Элементы.КомандаУдалить.Видимость       = Ложь;
		Элементы.КомандаДалее.КнопкаПоУмолчанию	= Истина;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура УстановитьПометкуВСписке(Данные, Пометка, ПроверятьРодителя)
	Данные.Пометка = Пометка;
	
	// Устанавливаем подчиненным
	ЭлементыСтроки = Данные.ПолучитьЭлементы();
	Для каждого Элемент Из ЭлементыСтроки Цикл
		УстановитьПометкуВСписке(Элемент, Пометка, Ложь);
	КонецЦикла;
	// Проверяем родителя
	Родитель = Данные.ПолучитьРодителя();
	Если проверятьРодителя И Родитель <> Неопределено Тогда 
		ПометкаРодителя = Истина;
		ЭлементыСтроки = Родитель.ПолучитьЭлементы();
		Для каждого Элемент Из ЭлементыСтроки Цикл
			Если НЕ Элемент.Пометка Тогда
				ПометкаРодителя = Ложь;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Если ПометкаРодителя <> Родитель.Пометка Тогда
			Родитель.Пометка = ПометкаРодителя;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры





	

